﻿using System;
using System.ServiceProcess;
using System.Threading;
using Hjt212Parser;
using log4net;
using System.Linq;
using MissingReissue.Properties;
using HpSocketIotGateway.Db.Code1st;
using System.Collections.Generic;

namespace HpSocketIotGateway
{
    public partial class MissingReissue : ServiceBase
    {
        private static readonly ILog Log = LogManager.GetLogger(typeof(MissingReissue));
        /// <summary>
        /// 初始化
        /// </summary>
        public MissingReissue()
        {
            try
            {
                InitializeComponent();
            }
            catch (Exception ex)
            {
                Log.Error(ex);
            }
        }

        public void Main()
        {
            OnStart(null);
        }
        /// <summary>
        /// Windows服务启动接口，启动后依次运行各回调方法和线程
        /// </summary>
        /// <param name="args"></param>
        protected override void OnStart(string[] args)
        {
            ServerThreadStart();
        }

        private void ServerThreadStart()
        {
            try
            {
                new Thread(StartServerThread) { IsBackground = true }.Start();
            }
            catch (Exception ex)
            {
                Log.Error(ex);
            }


        }
        /// <summary>
        /// 服务停止后
        /// </summary>
        protected override void OnStop()
        {
            try
            {
                Environment.Exit(0);
            }
            catch (Exception ex)
            {
                Log.Error(ex);
            }

        }

        private void StartServerThread(object state)
        {
            //bool isFirst = true;
            while (true)
            {
                try
                {
                    using (var ctx = new GatewayContext())
                    {
                        var mn_list = ctx.received_msg.Where(t => !t.mn.Contains(".")).Select(t => t.mn).Distinct().ToList();
                        DateTime now = DateTime.Now;
                        now = new DateTime(now.Year, now.Month, now.Day, 0, 0, 0);
                        var end = now.AddDays(-1);
                        var begin = end.AddDays(-Settings.Default.time_normal_loop_days);
                        var tablesSql = "SELECT table_name FROM information_schema.`tables` WHERE table_name LIKE 'received_msg%' AND table_name >= 'received_msg" + begin.ToString("yyyy") + "'";
                        var tables = ctx.Database.SqlQuery<string>(tablesSql).ToList();
                        foreach (var table in tables)
                        {
                            var sql = "SELECT DISTINCT mn from " + table + " WHERE mn NOT LIKE '%.%'";
                            var mns = ctx.Database.SqlQuery<string>(sql).ToList();
                            foreach (var mn in mns)
                            {
                                if (!mn_list.Contains(mn))
                                {
                                    mn_list.Add(mn);
                                }
                            }
                        }

                        Log.Debug("MN count:" + mn_list.Count);

                        //if (isFirst)
                        //{
                        //    isFirst = false;
                        //    reissueHour(ctx, mn_list, tables, begin, end);
                        //    reissueDay(ctx, mn_list, tables, begin, end);
                        //}

                        //end = now.AddDays(-1);
                        //begin = end.AddDays(-Settings.Default.time_normal_loop_days);
                        reissueDay(ctx, mn_list, tables, begin, end);

                        reissueHour(ctx, mn_list, tables, begin, end);

                        Log.Debug("One time processing finished!");
                    }

                }
                catch (Exception ex)
                {
                    Log.Error(ex);
                }
                finally
                {
                    ThreadUtil.Sleep(Settings.Default.interval_minutes * 60 * 1000);
                }
            }
        }

        private static void reissueHour(GatewayContext ctx, List<string> mn_list, List<string> tables, DateTime begin, DateTime end)
        {
            foreach (var mn in mn_list)
            {
                for (var time = begin; time <= end; time = time.AddHours(1))
                {
                    var isExsit = false;
                    foreach (var table in tables)
                    {
                        var countSql = "select count(1) from " + table + " where cn='2061' and mn='" + mn + "' and datatime>= '" + time.AddMinutes(-30).ToString("yyyy-MM-dd HH:mm:ss") + "' and datatime<='" + time.AddMinutes(30).ToString("yyyy-MM-dd HH:mm:ss") + "'";
                        var count = ctx.Database.SqlQuery<int>(countSql).FirstOrDefault();
                        if (count > 0)
                        {
                            isExsit = true;
                            break;
                        }
                    }
                    if (!isExsit)
                    {
                        var now = DateTime.Now;
                        var temp = "QN=" + now.ToString("yyyyMMddHHmmssfff") +
                               ";ST=31;CN=2061;PW=123456;MN=" + mn + ";Flag=1;CP=&&BeginTime=" +
                               time.ToString("yyyyMMddHHmmss") + ",EndTime=" +
                               time.ToString("yyyyMMddHHmmss") + "&&";
                        var responseMessage =  Crc.WrapByCrc(temp, "monitor");
                        var sentData = new send_data()
                        {
                            send_time = time,
                            send_string = responseMessage,
                            is_sent = false,
                            sent_time = null,
                            qn = now.ToString("yyyyMMddHHmmssfff"),
                            cn = "2061",
                            mn = mn
                        };
                        ctx.send_data.Add(sentData);
                        Log.Debug(responseMessage);
                        ctx.SaveChanges();
                    }

                }

            }
        }


        private static void reissueDay(GatewayContext ctx, List<string> mn_list, List<string> tables, DateTime begin, DateTime end)
        {
            foreach (var mn in mn_list)
            {
                for (var time = begin; time <= end; time = time.AddDays(1))
                {
                    var isExsit = false;
                    foreach (var table in tables)
                    {
                        var countSql = "select count(1) from " + table + " where cn='2031' and mn='" + mn + "' and datatime>= '" + time.AddMinutes(-30).ToString("yyyy-MM-dd HH:mm:ss") + "' and datatime<='" + time.AddMinutes(30).ToString("yyyy-MM-dd HH:mm:ss") + "'";
                        var count = ctx.Database.SqlQuery<int>(countSql).FirstOrDefault();
                        if (count > 0)
                        {
                            isExsit = true;
                            break;
                        }
                    }
                    if (!isExsit)
                    {
                        var now = DateTime.Now;
                        var temp = "QN=" + now.ToString("yyyyMMddHHmmssfff") +
                               ";ST=31;CN=2031;PW=123456;MN=" + mn + ";Flag=1;CP=&&BeginTime=" +
                               time.ToString("yyyyMMddHHmmss") + ",EndTime=" +
                               time.ToString("yyyyMMddHHmmss") + "&&";
                        var responseMessage =Crc.WrapByCrc(temp, "monitor") ;
                        var sentData = new send_data()
                        {
                            send_time = time,
                            send_string = responseMessage,
                            is_sent = false,
                            sent_time = null,
                            qn = now.ToString("yyyyMMddHHmmssfff"),
                            cn = "2031",
                            mn = mn
                        };
                        ctx.send_data.Add(sentData);
                        Log.Debug(responseMessage);
                        ctx.SaveChanges();
                    }

                }

            }
        }
    }
}
